package com.bibrApp.difu.actvity.uaccount_info_mvp;

import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.annotation.SuppressLint;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbEndpoint;
import android.hardware.usb.UsbInterface;
import android.hardware.usb.UsbManager;
import android.os.AsyncTask;
import android.text.TextUtils;
import android.util.Log;
import android.widget.TextView;

import com.bibrApp.difu.BeemIntent;
import com.bibrApp.difu.R;
import com.bibrApp.difu.base.BaseActivity;
import com.bibrApp.difu.proto2javabean.FeatureBean;
import com.bibrApp.difu.utils.ClsPublicUtils;
import com.bibrApp.difu.utils.DialogUtils;
import com.bibrApp.difu.utils.Protocol;
import com.bibrApp.difu.utils.ToastUtils;
import com.google.gson.Gson;
import com.google.protobuf.InvalidProtocolBufferException;
import com.googlecode.protobuf.format.JsonFormat;
import com.satoshilabs.trezor.lib.protobuf.TrezorMessageManagement;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import butterknife.BindView;
import butterknife.OnClick;

public class UAccountInfoActivity extends BaseActivity<UAccountInfoPresenter> implements IUAccountInfoView {


    @BindView(R.id.recycler_view)
    RecyclerView recyclerView;
    @BindView(R.id.tv_name)
    TextView tv_name;
    private AccountInfoAdapter adapter;
    List<AccountInfoBean> datas =new ArrayList<>();
    private UsbManager usbManager;
    private UsbDevice mUsbDevice;
    private UsbInterface mUsbInterface;
    private UsbDeviceConnection mUsbDeviceConnection;
    private UsbEndpoint usbEndpointIn;
    private UsbEndpoint usbEndpointOut;
    private Context mContext;
    @Override
    protected void initPresenter() {

        presenter = new UAccountInfoPresenter(this, this);
        presenter.init();
    }

    @Override
    protected int getLayoutId() {
        return R.layout.activity_uaccount_info;
    }


    @Override
    public void error(String msg) {

    }

    @Override
    public void success(String msg) {

    }

    @Override
    public void initView() {
        mContext = this;
        usbManager = (UsbManager) mContext.getSystemService(Context.USB_SERVICE);
        tv_name.setText(TextUtils.isEmpty(app.getuAccountName())?"DF-UKey":app.getuAccountName());
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        adapter = new AccountInfoAdapter();
        recyclerView.setAdapter(adapter);

        adapter.setOnItemChildClickListener((adapter1, view, position) -> {
            datas.add(new AccountInfoBean());
            adapter.setNewData(datas);
        });
        datas.add(new AccountInfoBean());
        adapter.setNewData(datas);
        checkUsb();
    }

    private void checkUsb() {
        if (usbManager == null) {
            return;
        }
        HashMap<String, UsbDevice> deviceHashMap = usbManager.getDeviceList();
        Iterator<UsbDevice> deviceIterator = deviceHashMap.values().iterator();
        ArrayList<String> usbDeviceList = new ArrayList<>();//存放usb数量
        while (deviceIterator.hasNext()) {
            UsbDevice device = deviceIterator.next();
            usbDeviceList.add(String.valueOf(device.getVendorId()));
            usbDeviceList.add(String.valueOf(device.getProductId()));
            if (device.getVendorId() == 0x1209 && device.getProductId() == 0x53C1) {//找到我们的usb设备
                ToastUtils.ShowToast(mContext, "找到了对应的usb设备（硬件钱包）");
                mUsbDevice = device;
            }
        }
        //请求权限
        if (mUsbDevice == null) {
            ToastUtils.ShowToast(mContext, "没找到对应的usb设备");
            return;
        }
        if (usbManager.hasPermission(mUsbDevice)) {
            findIntfAndEpt();
        } else {
            getUsbPermission(mUsbDevice);
        }
    }

    private void findIntfAndEpt() {
        if (mUsbDevice == null) {
            ToastUtils.ShowToast(mContext, "没有找到相匹配的设备");
            return;
        }
        if (mUsbDevice.getInterfaceCount() <= 0) {
            showToast("没有找到接口");
            return;
        }
        mUsbInterface = mUsbDevice.getInterface(0);
        //打开设备，获取UsbDeviceConnection对象，连接设备，用于后面的通讯
        UsbDeviceConnection usbDeviceConnection = usbManager.openDevice(mUsbDevice);
        if (usbDeviceConnection == null) {
            ToastUtils.ShowToast(mContext, "连接失败");
            return;
        }
        if (usbDeviceConnection.claimInterface(mUsbInterface, true)) {
            //找到接口
            mUsbDeviceConnection = usbDeviceConnection;
            //用于UsbDeviceConnection与UsbInterface进行端点设置和通讯
            if (mUsbInterface.getEndpoint(0) != null) {
                usbEndpointIn = mUsbInterface.getEndpoint(0);
            }
            if (mUsbInterface.getEndpoint(1) != null) {
                usbEndpointOut = mUsbInterface.getEndpoint(1);
            }
            showToast("设备已连接");
            initU();
        } else {
            //断开连接
            usbDeviceConnection.close();
        }
    }
    private void initU() {
        int ret = -100;
        TrezorMessageManagement.Initialize.Builder initBuild = TrezorMessageManagement.Initialize.newBuilder();
        TrezorMessageManagement.Initialize initialize = initBuild.build();//组装成对应的protobuf文件中的方法
        byte[] init = initialize.toByteArray();//转成16进制

        if (mUsbDeviceConnection == null) {
            ToastUtils.ShowToast(mContext, "没有建立连接");
            checkUsb();
            return;
        }
        //添加协议
        List<byte[]> bytes = Protocol.encode(0, init);
        // 1,发送准备命令
        //通过usb hid传输数据给u盾
        for (int i = 0; i < bytes.size(); i++) {
            byte [] sendbytes = bytes.get(i);
            ret = mUsbDeviceConnection.bulkTransfer(usbEndpointOut, sendbytes, sendbytes.length, 5000);
        }
        if (ret == 64) {
            getHidMsg();
        }

    }

    private FeatureBean featureBean;

    @SuppressLint("StaticFieldLeak")
    public void getHidMsg() {
        new AsyncTask<String, Integer, List<byte[]>>() {
            @Override
            protected void onPreExecute() {
                super.onPreExecute();
                //开始接受信息
                DialogUtils.showDialog(mContext);
            }

            @Override
            protected List<byte[]> doInBackground(String... params) {
                List<byte[]> byteRe = new ArrayList<>();
                try {
                    boolean isContinue = true;
                    while (isContinue) {
                        byte[] recByte = new byte[64];
                        mUsbDeviceConnection.bulkTransfer(usbEndpointIn, recByte, recByte.length, 10000);
                        byteRe.add(recByte);
                        if (Protocol.hasHead(recByte)) {
                            byteRe.add(recByte);
                        } else {
                            isContinue = false;
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return byteRe;
            }

            @Override
            protected void onPostExecute(List<byte[]> bytes) {
                if (bytes == null || bytes.size() == 0) {
                    //接受信息失败
                    DialogUtils.dismissDialog();
                    return;
                }
                String decodeStr = Protocol.decode(bytes);
                Log.d("dj", "====解码之后===" + decodeStr);
                try {
                    TrezorMessageManagement.Features features = TrezorMessageManagement.Features.parseFrom(ClsPublicUtils.hexToBytes(decodeStr));
                    String asJson = JsonFormat.printToString(features);
                    featureBean = new Gson().fromJson(asJson, FeatureBean.class);
                    tv_name.setText(featureBean.getLabel());
                    Log.d("dj", "=====" + asJson);
                } catch (InvalidProtocolBufferException e) {
                    e.printStackTrace();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                DialogUtils.dismissDialog();
            }

        }.execute();
    }
    private Receiver mUsbReceiver;
    //开始申请USB权限
    private void getUsbPermission(UsbDevice mUSBDevice) {
        PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(BeemIntent.ACTION_USB_INTENT), 0);
        IntentFilter filter = new IntentFilter(BeemIntent.ACTION_USB_INTENT);
        filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
        filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
        mUsbReceiver = new Receiver();
        mContext.registerReceiver(mUsbReceiver, filter);
        usbManager.requestPermission(mUSBDevice, pendingIntent); // 该代码执行后，系统弹出一个对话框/等待权限
    }

    private class  Receiver extends BroadcastReceiver {
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();

            if (BeemIntent.ACTION_USB_INTENT.equals(action)) {
                synchronized (this) {
                    UsbDevice device = (UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
                    if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)
                            && mUsbDevice.equals(device)) {
                        //TODO 授权成功，操作USB设备
                        ToastUtils.ShowToast(mContext, "usb授权成功");
//                        findIntfAndEpt();
                    } else {
                        //用户点击拒绝了
                        ToastUtils.ShowToast(mContext, "拒绝usb授权");
                    }
                }
            }
        }
    }

    @OnClick(R.id.bt_back)
    public void backClick() {
        finish();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if(mUsbReceiver != null){
            unregisterReceiver(mUsbReceiver);
        }
    }
}
